"""
Case Type   : explain table
Case Name   : explain查询mot表结构信息
Create At   : 2023-01-09
Owner       : @zou_jialiang0501162244
Description :
    1.设置enable_incremental_checkpoint=off,重启数据库
    2.创建兼容B库
    3.B库下创建MOT表并插入数据
    4.explain查看MOT表结构
    5.清理环境
Expect      :
    1.成功
    2.成功
    3.成功
    4.返回表结构
    5.成功
History     :
    modified by @zou_jialiang050,2023.03.28，修改断言信息确保Degraded断言成功
    modified by @zou_jialiang050,2023.03.31，优化断言信息
"""

import os
import unittest
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class Explain(unittest.TestCase):

    def setUp(self):
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.comm = Common()
        self.constant = Constant()
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.db_name = 'db_explain_0011'
        self.tb_name = 't_explain_0011'

    def test_explain_table(self):
        text1 = '-----step1:设置参数并重启数据库;expect:成功-----'
        self.log.info(text1)
        self.param = self.comm.show_param('enable_incremental_checkpoint')
        if 'off' not in self.param:
            guc_res = self.pri_sh.execute_gsguc(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                'enable_incremental_checkpoint = off')
            guc_res1 = self.pri_sh.execute_gsguc(
                "set", self.constant.GSGUC_SUCCESS_MSG,
                f'enable_mot_server=on')
            self.log.info(guc_res1)
            self.log.info(guc_res)
            self.assertTrue(guc_res, f'设置guc参数失败:{text1}')
            self.assertTrue(guc_res1, f'设置guc参数失败:{text1}')
            restart_res = self.pri_sh.restart_db_cluster(False)
            self.log.info(restart_res)
            stat_res = self.pri_sh.get_db_cluster_status()
            self.assertTrue("Degraded" in stat_res or "Normal" in stat_res,
                            f'执行失败:{text1}')

        text2 = '-----step2:创建兼容B库 expect:创建成功-----'
        self.log.info(text2)
        create_db = f"drop database if exists {self.db_name}; " \
                    f"create database {self.db_name} dbcompatibility='B';"
        db_res = self.pri_sh.execut_db_sql(create_db)
        self.log.info(db_res)
        self.assertIn(self.constant.CREATE_DATABASE_SUCCESS, db_res,
                      f'执行失败:{text2}')

        text3 = '-----step3:B库下创建MOT表并插入数据;expect:成功-----'
        self.log.info(text3)
        sql = f"drop foreign table if exists {self.tb_name} cascade; " \
              f"create foreign table {self.tb_name}(" \
              f"id int not null,name varchar(10)); " \
              f"insert into {self.tb_name} values(1, 'Bitmap');"
        sql_res = self.pri_sh.execut_db_sql(sql, dbname=self.db_name)
        self.log.info(sql_res)
        self.assertIn(self.constant.CREATE_FOREIGN_SUCCESS_MSG, sql_res,
                      f'建表失败:{text3}')
        self.assertIn(self.constant.INSERT_SUCCESS_MSG, sql_res,
                      f'表中插入数据失败:{text3}')

        text4 = 'step4:explain查看MOT表结构;expect:返回表结构'
        self.log.info(text4)
        explain_tb = self.pri_sh.execut_db_sql(f"explain {self.tb_name}",
                                               dbname=self.db_name)
        self.log.info(explain_tb)
        exp_msg1 = "id    | integer               | NO   |     | NULL"
        exp_msg2 = "name  | character varying(10) | YES  |     | NULL"
        self.assertIn(exp_msg1, explain_tb, f'执行失败:{text4}')
        self.assertIn(exp_msg2, explain_tb, f'执行失败:{text4}')

    def tearDown(self):
        text5 = '-----step5:清理环境 expect:成功-----'
        self.log.info(text5)
        drop_db = self.pri_sh.execut_db_sql(f"drop database {self.db_name};")
        self.log.info(drop_db)
        guc_res = self.pri_sh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'enable_incremental_checkpoint={self.param}')
        self.log.info(guc_res)
        restart_res = self.pri_sh.restart_db_cluster(False)
        self.log.info(restart_res)
        stat_res = self.pri_sh.get_db_cluster_status()
        curr_value = self.comm.show_param('enable_incremental_checkpoint')
        self.log.info(curr_value)
        self.assertIn(self.constant.DROP_DATABASE_SUCCESS, drop_db,
                      f'删除数据库失败:{text5}')
        self.assertTrue(guc_res, f'恢复guc参数失败:{text5}')
        self.assertTrue("Degraded" in stat_res or "Normal" in stat_res,
                        f'执行失败:{text5}')
        self.assertEqual(self.param, curr_value, f'执行失败:{text5}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
